package com.atguigu.gulimall.order.service.impl;

import com.atguigu.gulimall.order.entity.OrderEntity;
import com.atguigu.gulimall.order.entity.OrderReturnReasonEntity;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.order.dao.OrderItemDao;
import com.atguigu.gulimall.order.entity.OrderItemEntity;
import com.atguigu.gulimall.order.service.OrderItemService;


@Service("orderItemService")
@RabbitListener(queues = {"hello-java-queue"})
public class OrderItemServiceImpl extends ServiceImpl<OrderItemDao, OrderItemEntity> implements OrderItemService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        IPage<OrderItemEntity> page = this.page(
                new Query<OrderItemEntity>().getPage(params),
                new QueryWrapper<OrderItemEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 1.在我们实际开发中，我们只需要消息体，即真正的数据，SpringMVC自动可以为我们参数绑定，即
     * 传进去一个真正数据对应的类，便自动帮助我们从JSON反序列化为原先的对象，而不需要我们手动反序列化，
     * 做法就是只需要多接受一个参数就行，参数的类型就是你要接收到的类型
     *
     * 2.最后，我们还可以添加一个参数，就是接受该消息所对应的通道Channel。至于什么意思，我们稍后再说
     *
     * 3.订单服务启动多个，同一个消息，只能有一个客户端收到
     *
     * 4.只有一个消息完全处理完(即该方法完全运行完成)，我们才能接受到下一个消息
     * @param message 接收到的消息的“全部数据”
     * @param content 反序列化的实际可用数据
     * @param channel 接收该队列消息的通道
     */
//    @RabbitListener(queues = {"hello-java-queue"})
    @RabbitHandler
    public void receive(Message message,
                        OrderReturnReasonEntity content,
                        Channel channel){
        System.out.println("1111111111111");
        //{"id":1,"name":"哈哈","sort":null,"status":null,"createTime":1581144531744}
        byte[] body = message.getBody();
        //消息头属性信息
        //headers={__TypeId__=com.atguigu.gulimall.order.entity.OrderReturnReasonEntity}, contentType=application/json, contentEncoding=UTF-8, .........
        MessageProperties properties = message.getMessageProperties();
        /**
         * basicAck(long deliveryTag,  当前消息的派发的标签，是一个数字
         *          boolean multiple)  是不是批量确认,false意思是我只签收当前货物
         *
         * deliveryTag:与消息一一对应，并且是通道内自增，比如一个消息来了就是1，第二个消息来了就是2，按照顺序自增
         */
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        System.out.println("deliveryTag: ["+deliveryTag+"]");
        //签收货物，非批量签收
        try {
            //下面的条件判断是在模拟服务器运行正常和服务器宕机
            if(deliveryTag%2==0){
                channel.basicAck(deliveryTag,false);
                System.out.println("成功签收了: "+deliveryTag);
            }else{
                //long deliveryTag, boolean multiple(是否批量拒绝), boolean requeue(是否消息重新入队。false:丢弃、true:发回服务器，重新入队)
                channel.basicNack(deliveryTag,false,true);
                //long deliveryTag, boolean requeue
//                channel.basicReject();
                System.out.println("拒绝签收了: "+deliveryTag);
            }

        } catch (IOException e) {

            e.printStackTrace();
        }
        System.out.println("接收到的消息是:"+content+"....类型是"+content.getClass());
    }


    @RabbitHandler
    public void receive1(Message message,
                         OrderEntity content,
                         Channel channel){
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        System.out.println("deliveryTag: ["+deliveryTag+"]");
        try {
            channel.basicAck(deliveryTag,false);
        } catch (IOException e) {

            e.printStackTrace();
        }
        System.out.println("接收到的消息是:"+content+"....类型是"+content.getClass());
    }

}